using Engine.Graphics;
using System.Diagnostics;
using System.IO;

namespace ForestBorder
{
    internal struct Properties
    {
        #region Private Fields

        private const byte versionsNumber = 0x02;
        private float heightEnd;
        private float heightOffset;
        private float heightStart;
        private Material material;
        private float texturCoordinateScale;
        private float textureOffsetStarts;

        #endregion Private Fields

        #region Internal Constructors

        internal Properties(float heightStart, float heightEnd, Material material)
        {
            // Version 0
            this.heightStart = heightStart;
            this.heightEnd = heightEnd;
            this.material = material;
            this.textureOffsetStarts = 0.0f;
            this.heightOffset = 0.0f;
            this.texturCoordinateScale = 2.0f;
        }

        internal Properties(float heightStart, float heightEnd, float textureOffset, Material material)
            : this(heightStart, heightEnd, material)
        {
            // Version 1
            this.textureOffsetStarts = textureOffset;
        }

        internal Properties(float heightStart, float heightEnd, float textureOffset, Material material, float offsetY, float textureScale)
            : this(heightStart, heightEnd, textureOffset, material)
        {
            // Version 2
            this.texturCoordinateScale = textureScale;
            this.heightOffset = offsetY;
        }

        #endregion Internal Constructors

        #region Public Properties

        public float HeightEnd
        {
            get { return heightEnd; }
            set { heightEnd = value; }
        }

        public float HeightOffset
        {
            get { return heightOffset; }
            set { heightOffset = value; }
        }

        public float HeightStart
        {
            get { return heightStart; }
            set { heightStart = value; }
        }

        public Material Material
        {
            get { return material; }
            set { material = value; }
        }

        public float TexturCoordinateScale
        {
            get { return texturCoordinateScale; }
            set { texturCoordinateScale = value; }
        }

        public float TextureOffsetStarts
        {
            get { return textureOffsetStarts; }
            set { textureOffsetStarts = value; }
        }

        #endregion Public Properties

        #region Internal Methods

        internal static Properties FromStream(BinaryReader br)
        {
            byte version = br.ReadByte();

            switch (version)
            {
                case 0x01:// Version 1
                    return new Properties(br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), Material.FromStream(br));

                case 0x02:// Version 2
                    return new Properties(br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), Material.FromStream(br), br.ReadSingle(), br.ReadSingle());
            }
            Debug.WriteLine("Error while loading properties from ForestBorder Addin!");

            return new Properties(100, 100, new Material("empty", "empty", "empty", EnumMappingMode.material32));
        }

        internal void Save(System.IO.BinaryWriter writer)
        {
            writer.Write(Properties.versionsNumber);
            writer.Write(this.heightStart);
            writer.Write(this.heightEnd);
            writer.Write(this.TextureOffsetStarts);
            this.material.SaveToStream(writer);
            writer.Write(this.HeightOffset);
            writer.Write(this.TexturCoordinateScale);
        }

        #endregion Internal Methods
    }
}